/*
 *  Copyright (C) 2010 Glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.builder;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JTable;
import org.balisunrise.annotation.util.AnnotationsUtilitiesException;
import org.balisunrise.annotation.util.ColumnUtilities;
import org.balisunrise.annotation.util.GridUtilities;
import org.balisunrise.application.Application;
import org.balisunrise.builder.FactoryException;
import org.balisunrise.builder.BuilderException;
import org.balisunrise.common.Grid;
import org.balisunrise.common.GridColumn;
import org.balisunrise.swing.components.util.TableFocusListener;
import org.balisunrise.swing.transaction.panel.actions.TableEnterAction;
import org.balisunrise.swing.transaction.BaliGridModel;

/**
 *
 * @author Glauco
 */
public class BaliGridBuilder implements org.balisunrise.builder.GridBuilder{

    private static final String MESSAGE = "Erro ao construir um BaliGrid.\n";

    public Grid create(Class entityClass, String alias)
            throws BuilderException {

        if(entityClass == null){
            throw new BuilderException(MESSAGE +
                    "entityClass não pode ser nulo.");
        }

        if(alias == null){
            throw new BuilderException(MESSAGE +
                    "alias não pode ser nulo.");
        }

        try{
            GridUtilities gu = GridUtilities.create(entityClass, alias);
            return create(gu);
        }catch(AnnotationsUtilitiesException aue){
            throw new BuilderException(MESSAGE +
                    aue.getMessage(), aue.getCause());
        }
    }

    public Grid create(GridUtilities gridUtilities)
            throws BuilderException {

        if(gridUtilities == null){
            throw new BuilderException(MESSAGE +
                    "gridUtilities não pode ser nulo.");
        }

        // cria Grid
        org.balisunrise.swing.transaction.BaliGrid grid =
                new org.balisunrise.swing.transaction.BaliGrid();
        grid.setAlias(gridUtilities.alias);
        grid.setEntityClass(gridUtilities.entityClass);

        // cria colunas GridColumn
        List<GridColumn> columns = new ArrayList<GridColumn>();
        for (ColumnUtilities cUtil : gridUtilities.columns) {
            try{
                GridColumn[] cols = Application.get().getFactory()
                    .createGridColumn(gridUtilities.entityClass, cUtil);
                for (GridColumn col : cols) {
                    col.setOwner(grid);
                    columns.add(col);
                }
            }catch (FactoryException fex){
                throw new BuilderException(MESSAGE + "\n"
                        + fex.getMessage());
            }
        }

        // cria BaliGridModel
        BaliGridModel gridModel = new BaliGridModel();
        gridModel.setAlias(gridUtilities.alias);
        gridModel.setEntityClass(gridUtilities.entityClass);
        gridModel.setColumns(columns.toArray(new GridColumn[]{}));
        gridModel.setOwner(grid);

        // atribui gridModel
        grid.setGridModel(gridModel);

        // cria tabela (JTable - the GRID)
        JTable table = new JTable(gridModel);
        String name = gridUtilities.entityClass.getName() +
                "_baligrid_" + gridUtilities.alias;
        table.setName(name);
        table.getAccessibleContext().setAccessibleName(name);
        grid.setName(name);

        // Calcula e Atribui Dimenções
        int totalWidth = 0;
        for(int i = 0; i < gridModel.getColumns().length; i++){
            int width = gridModel.getColumns()[i].getWidth();
            if (width == 0)
                width = 100;
            table.getColumnModel().getColumn(i).setPreferredWidth(width);
            table.getColumnModel().getColumn(i).setMinWidth(width);
            totalWidth += width;
        }
        if (gridUtilities.width > 0){
            totalWidth = gridUtilities.width;
        }
        // Tamanho do table
        Dimension dimension = new Dimension(totalWidth , gridUtilities.height);
        // Dimensiona o table
        table.setMinimumSize(dimension);
        //table.setPreferredSize(dimension);
        table.setPreferredScrollableViewportSize(dimension);

        // outras propriedades
        //table.setSurrendersFocusOnKeystroke(true);
        table.setUpdateSelectionOnSort(false);
        TableEnterAction action = new TableEnterAction(table);
        table.addFocusListener(new TableFocusListener(table));

        // atribui representação visual
        grid.setVisualRepresentation(table);

        return grid;
    }


}
